#pragma once

#pragma unmanaged

#pragma managed
#include "..\Entity.h"
using namespace System::Collections::Generic;

namespace ManagedAPI
{
	public ref class MethodType : public Entity
	{
	public: 
		static MethodType^ Create(const UdbEntity&);
		static void Clear();
		property array<Entity^>^ Parameters
		{
			array<Entity^>^ get();
		}
		// Uses the underlying API to quickly get a string of parameters.
		// Pass in true to get the parameter names, false otherwise.
		//String^ GetParameters(bool);
		property String^ Attributes
		{
			String^ get();
		}
		property bool IsAbstract { bool get(); }
		property bool IsVirtual { bool get(); }
		property bool IsConstructor  { bool get(); }
		property bool IsPrivate { bool get(); }
		property bool IsPublic { bool get(); }
		property bool IsProtected { bool get(); }
		property bool IsStatic { bool get(); }
		property bool IsInline { bool get(); }
		
		// Gets the parameters if this represents a method.
		// TODO: Move this to: MethodType.
		String^      GetParameters(bool);

		//String^ ParametersToString();
		//String^ ParameterTypesToString();
		// If this method is virtual, get's any methods that override this method.
		// If the method is non-virtual, then it returns an empty array.
		array<MethodType^>^ GetOverrides();
		virtual String^ ToString() override;
		virtual String^ ToString(bool, bool);

		// Gets the line numbers for a function declaration by using the lexer and lexeme's.
		// This is especially useful for function declarations that span multiple lines.
		void GetLexLineNumbers(int%, int%);
	protected:
		MethodType(const UdbEntity&);
	private:
		array<Entity^>^ mParameters;
		List<MethodType^>^ mOverRides;
		//String^ BuildParameterString(bool);
		String^ mAttributes;
		int mAttributesFlag;
		int mIsConstructor;
		int mIsProtected;

		template<typename T> array<T^>^ GetTypes(String^ refkinds, String^ entkinds);

		static Dictionary<String^, MethodType^>^ sMethodList = gcnew Dictionary<String^, MethodType^>();
	};
}